﻿// owner 蒋家伟

#pragma once
#include "TaskBase_home.h"
#include "TaskRegisterUtils.h"

namespace jsdk
{
    class ITaskDescription;
    class ITaskExectutable;
    // 类别描述 : 任务注册助手，将描述与执行者匹配，由框架去帮忙找寻任务的执行手段。直接调用Task::Excute即可。
    // 注意     : 请使用下面的宏而非直接使用模板类型
    template<typename TaskDescription, typename TaskExecutable>
    class TaskRegisterHelper
    {
        static_assert(std::is_base_of<ITaskDescription, TaskDescription>::value, "任务描述必须继承ITaskDescription");
        static_assert(std::is_base_of<ITaskExectutable, TaskExecutable>::value, "任务执行者必须继承ITaskExectutable");
    public:
        TaskRegisterHelper() 
        {
            TaskRegisterUtils::registerTaskExecutable(TaskDescription::task_Descrition_Define(), []() {return std::make_unique<TaskExecutable>(); });
        }
    };
}

/// \ brief 任务描述的声明，放在任务描述的声明处，一般是.h文件
/// \ CLASSNAME             描述对应的类别名称
/// \ TASK_EXECUTOR         任务的执行者，所有的执行者必须是一个设备。最好把所有设备的名称定义在一个文件里，方便注册的时候使用。
/// \ TASK_DESCRIPTION      当前任务的描述，表示这个任务是干什么的
#define TASK_DESCRIPTION_DECLARE(CLASSNAME, TASK_EXECUTOR , TASK_DESCRIPTION)   \
public : \
static constexpr wchar_t* task_Descrition_Define()  \
{\
    return TASK_DESCRIPTION;                        \
};\
private : \
virtual std::wstring getDescription() const override \
{\
    return task_Descrition_Define();                 \
};\
virtual std::wstring getExecutorName() const override\
{\
    return TASK_EXECUTOR;\
};

/// \ brief 任务执行者的声明，放在任务执行者的声明处，一般是.h文件
/// \ NAMESPACE_0                        描述类别的命名空间namespace
/// \ TASK_DESCRIPTION_CLASSNAME         描述类别class
/// \ NAMESPACE_1                        执行类别的命名空间
/// \ TASK_EXECUTABLE_CLASSNAME          执行类别的class
#define TASK_EXECUTABLE_DECALRE(NAMESPACE_0, TASK_DESCRIPTION_CLASSNAME, NAMESPACE_1, TASK_EXECUTABLE_CLASSNAME)   \
public:\
TASK_EXECUTABLE_CLASSNAME ();\
private: \
static TaskRegisterHelper< NAMESPACE_0 :: TASK_DESCRIPTION_CLASSNAME , NAMESPACE_1 :: TASK_EXECUTABLE_CLASSNAME > s_##TASK_DESCRIPTION_CLASSNAME##_RegisterHelper; 

/// \ brief 任务执行者的定义，放在任务执行者的定义处，是.cpp文件
/// \ note1 : 宏定义的结束需要包含{}，在{}内部实现其默认构造函数
/// \ note2 : 任务的描述与执行者是"一 一 对 应" 的关系
/// \ note3 : 执行者不支持缓存数据，每次触发都是一个新的执行者对象
/// \ NAMESPACE_0                        描述类别的命名空间namespace
/// \ TASK_DESCRIPTION_CLASSNAME         描述类别class
/// \ NAMESPACE_1                        执行类别的命名空间
/// \ TASK_EXECUTABLE_CLASSNAME          执行类别的class
#define TASK_EXECUTABLE_DEFINE(NAMESPACE_0, TASK_DESCRIPTION_CLASSNAME, NAMESPACE_1, TASK_EXECUTABLE_CLASSNAME)   \
TaskRegisterHelper< NAMESPACE_0 :: TASK_DESCRIPTION_CLASSNAME , NAMESPACE_1 :: TASK_EXECUTABLE_CLASSNAME > NAMESPACE_1 :: TASK_EXECUTABLE_CLASSNAME :: s_##TASK_DESCRIPTION_CLASSNAME##_RegisterHelper; \
NAMESPACE_1 :: TASK_EXECUTABLE_CLASSNAME :: TASK_EXECUTABLE_CLASSNAME ()
